package eswc.cleaner;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import com.javadocmd.simplelatlng.LatLng;

import twitter4j.GeoLocation;
import twitter4j.Paging;
import twitter4j.Place;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;


public class TwitterLocationHistory implements LocationHistory {
	
	private final String name;

	public TwitterLocationHistory(String name) {
		this.name = name;
	}

	public List<CoordinateMark> getMarks() {
		Twitter twitter = new TwitterFactory().getInstance();
		
		Date yearAgo = yearAgo();
		
		Date lastDate = new Date();
		
		List<CoordinateMark> res = new ArrayList<CoordinateMark>();
		for (int page = 1;
			lastDate.compareTo(yearAgo) >= 0;
			page++) {
			try {
				List<Status> statuses = twitter.getUserTimeline(name, new Paging(page));
				System.out.print("Page: " + page + " retrieved. ");
				
				if (statuses.size() > 0) {
					Date firstDate = statuses.get(0).getCreatedAt();
					lastDate = statuses.get(statuses.size()-1).getCreatedAt();
					System.out.println("First tweet at " + firstDate + " last at " + lastDate);
				} else {
					System.out.println("No tweets found");
					break;
				}
				
				for (Status status: statuses) {
					GeoLocation loc = status.getGeoLocation();
					Place place = status.getPlace();
					if (loc != null) {
						System.out.println("Geolocation found!");
						CoordinateMark mark = new CoordinateMark(
							new LatLng(loc.getLatitude(), loc.getLongitude()),
							status.getCreatedAt());
						res.add(mark);
					} else {
						LatLng coords = tryGetPlaceCoords(status);
						if (coords != null) {
							System.out.println("Place found!");
							CoordinateMark mark = new CoordinateMark(
								coords,	status.getCreatedAt());
							res.add(mark);
						}
					}
				}
				
			} catch (TwitterException e) {
				e.printStackTrace();
				break;
			}
		}
		
		return res;
	}

	private LatLng tryGetPlaceCoords(Status status) {
		Place place = status.getPlace();
		
		if (place != null && place.getBoundingBoxCoordinates() != null) {
			double lat = 0.0;
			double lng = 0.0;
			GeoLocation[] locs = place.getBoundingBoxCoordinates()[0];
			
			for (GeoLocation loc: locs) {
				lat += loc.getLatitude();
				lng += loc.getLongitude();
			}
			
			return new LatLng(lat/locs.length, lng/locs.length);
		} else {
			return null;
		}
	}

	private Date yearAgo() {
		Calendar cal = new GregorianCalendar();
		
		cal.setTime(new Date());
		cal.roll(Calendar.YEAR, -1);
		Date yearAgo = cal.getTime();
		return yearAgo;
	}
	
	public static void main(String[] args) {
		TwitterLocationHistory hist = new TwitterLocationHistory("barrynorton");
		for (CoordinateMark m: hist.getMarks()) {
			System.out.println("Mark at " + m.getDate() + " coords: " + m.getCoordinates());
		}
	}
}
